import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

import core.engine.systemDBEngine;
import core.exceptions.DBEngineException;
import security.auth.UserManager;
import session.Session;
import storage.StorageException;
import storage.io.FileManager;
import storage.manager.DatabaseManager;

/**
 * Main 类是程序入口，提供一个简单的 SQL 交互界面。
 */
public class Main {
    
    // 保存用户会话映射，允许多个用户同时登录
    private static final Map<String, Session> userSessions = new HashMap<>();
    
    // 系统命令集合
    private static final Set<String> SYSTEM_COMMANDS = new HashSet<>(Arrays.asList(
        "exit", "backup", "create_db", "create_table", "insert_data", 
        "reset_system", "register", "login", "logout", "users", "databases", "delete_db", "unuse",
        "add_column", "drop_column"
    ));

    // SQL命令前缀集合
    private static final Set<String> SQL_COMMAND_PREFIXES = new HashSet<>(Arrays.asList(
        "select", "insert", "update", "delete", "create", "drop", "alter",
        "use", "show", "grant", "revoke", "commit", "rollback", "begin",
        "desc", "describe", "explain", "set", "truncate", "analyze", "attach",
        "detach", "vacuum", "pragma", "indexed"
    ));

    /**
     * 程序入口方法
     *
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        try {
            // 设置日志详细级别（生产环境可考虑设置为false减少日志输出）
            systemDBEngine.setVerboseLogging(false);

            System.out.println("============================");
            System.out.println("   数据库管理系统 启动中...   ");
            System.out.println("============================");

            // 确保存储目录已创建
            FileManager.initDBRoot();

            // 初始化系统数据库（保证基础功能）
            initializeSystem();

            Scanner scanner = new Scanner(System.in);
            boolean running = true;

            // 主循环
            while (running) {
                displayPrompt();
                String command = scanner.nextLine().trim();

                if (command.isEmpty()) {
                    continue;
                }

                if (command.equalsIgnoreCase("exit") || command.equalsIgnoreCase("quit")) {
                    running = false;
                    System.out.println("正在安全退出系统...");

                    // 关闭所有数据库连接
                    DatabaseManager.closeAllDatabases();
                    // 关闭系统数据库
                    systemDBEngine.closeSystemDB();

                    System.out.println("再见！");
                } else {
                    processCommand(command, scanner);
                }
            }

            scanner.close();

        } catch (Exception e) {
            System.err.println("系统启动失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 初始化系统
     * 检查系统数据库状态并在需要时初始化
     */
    private static void initializeSystem() {
        try {
            System.out.println("检查系统数据库初始化状态...");
            boolean isInitialized = systemDBEngine.checkSystemTablesInitialized();
            if (!isInitialized) {
                System.out.println("正在初始化系统数据库...");
                systemDBEngine.initSystemTables();
                System.out.println("系统数据库初始化完成");
            }
        } catch (Exception e) {
            System.err.println("系统初始化失败: " + e);
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            System.err.println("堆栈跟踪:\n" + sw.toString().replace("\t", "    "));
            System.exit(1);
        }

        System.out.println("欢迎使用简单 DBMS");
        System.out.println("默认管理员账户: admin，密码: 114514");
        System.out.println("🎯 系统命令: exit, backup, create_db, create_table, insert_data, reset_system, register, login, logout, users, databases, delete_db, unuse");
        System.out.println("🎯 SQL命令: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, USE, SHOW, 等标准SQL语句");
    }

    /**
     * 显示命令提示符
     * 根据当前用户和数据库状态显示不同的提示
     */
    private static void displayPrompt() {
        // 显示登录状态和权限级别
        String prompt;
        Session currentSession = Session.getCurrentSession();
        String currentUser = UserManager.getCurrentUser();

        if (currentUser == null) {
            prompt = "SQL> ";
        } else {
            int level = UserManager.getUserLevel(currentUser);
            String levelStr = level == UserManager.ADMIN_LEVEL ? "管理员" : "普通用户";
            
            String dbDisplayName = "未选择";
            if (currentSession != null) {
                String currentDbName = currentSession.getCurrentDatabaseName();
                String currentDbOwner = currentSession.getCurrentDatabaseOwnerName();
                if (currentDbName != null && currentDbOwner != null) {
                    dbDisplayName = currentDbOwner + "." + currentDbName;
                } else if (currentDbName != null) { // Fallback if owner is null for some reason
                    dbDisplayName = currentDbName + " (所有者未知)";
                } else if (currentDbOwner != null) { // Fallback if name is null (less likely)
                    dbDisplayName = currentDbOwner + ".? (名称未知)";
                }
            }
            prompt = "SQL(" + currentUser + "," + levelStr + ",当前库=" + dbDisplayName + ")> ";
        }

        System.out.print(prompt);
    }

    /**
     * 处理用户输入的命令
     *
     * @param command 用户输入的命令
     * @param scanner 命令行扫描器
     */
    private static void processCommand(String command, Scanner scanner) {
        // 获取命令类型
        String commandType = command.toLowerCase().split("\\s+")[0];

        // 处理系统命令
        if (SYSTEM_COMMANDS.contains(commandType)) {
            processSystemCommand(commandType, command, scanner);
        }
        // 处理SQL命令
        else if (SQL_COMMAND_PREFIXES.contains(commandType) || isValidSQLCommand(command)) {
            processSQL(command);
        }
        // 未知命令
        else {
            System.err.println("❌ 未知命令，请输入有效的系统命令或SQL语句");
        }
    }

    /**
     * 处理系统命令
     *
     * @param command 命令关键字
     * @param fullInput 完整输入
     * @param scanner 输入扫描器
     * @return 是否应该退出程序
     */
    private static boolean processSystemCommand(String command, String fullInput, Scanner scanner) {
        switch (command) {
            case "exit":
                System.out.println("👋 再见！");
                // 在退出前尝试关闭所有打开的数据库
                try {
                    DatabaseManager.closeAllDatabases();
                } catch (Exception e) {
                    System.err.println("关闭数据库时出现错误: " + e.getMessage());
                }
                return true;
            case "backup":
                handleBackupCommand(scanner);
                break;
            case "create_db":
                handleCreateDatabase(scanner);
                break;
            case "create_table":
                handleCreateTable(scanner);
                break;
            case "insert_data":
                handleInsertData(scanner);
                break;
            case "reset_system":
                handleResetSystem();
                break;
            case "register":
                handleUserRegistration(scanner);
                break;
            case "login":
                handleUserLogin(scanner);
                break;
            case "logout":
                handleUserLogout();
                break;
            case "users":
                handleShowUsers();
                break;
            case "databases":
                handleShowDatabases();
                break;
            case "delete_db":
                handleDeleteDatabase(scanner);
                break;
            case "unuse":
                handleUnuse();
                break;
            case "add_column":
                handleAddColumn(scanner);
                break;
            case "drop_column":
                handleDropColumn(scanner);
                break;
            default:
                System.err.println("❌ 未知系统命令: " + command);
        }
        return false;
    }

    /**
     * 检查输入是否是有效的SQL命令
     *
     * @param input 用户输入
     * @return 是否是SQL命令
     */
    private static boolean isValidSQLCommand(String input) {
        String normalizedInput = input.toLowerCase().trim();

        // 处理SQL注释
        if (normalizedInput.startsWith("--") || normalizedInput.startsWith("/*")) {
            return true;
        }

        // 检查是否以SQL命令前缀开头
        for (String prefix : SQL_COMMAND_PREFIXES) {
            if (normalizedInput.startsWith(prefix + " ") ||
                normalizedInput.equals(prefix) ||
                normalizedInput.startsWith(prefix + "(")) {
                return true;
            }
        }

        // 检查是否是带分号的SQL命令
        if (normalizedInput.endsWith(";")) {
            String withoutSemicolon = normalizedInput.substring(0, normalizedInput.length() - 1).trim();
            for (String prefix : SQL_COMMAND_PREFIXES) {
                if (withoutSemicolon.startsWith(prefix + " ") ||
                    withoutSemicolon.equals(prefix) ||
                    withoutSemicolon.startsWith(prefix + "(")) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 处理用户注册
     * @param scanner 输入扫描器
     */
    private static void handleUserRegistration(Scanner scanner) {
        System.out.print("请输入用户名: ");
        String username = scanner.nextLine().trim();
        System.out.print("请输入密码: ");
        String password = scanner.nextLine().trim();
        System.out.print("请输入权限级别 (1=管理员, 2=普通用户，默认为2): ");
        String levelStr = scanner.nextLine().trim();

        int level = UserManager.NORMAL_LEVEL; // 默认为普通用户
        if (!levelStr.isEmpty()) {
            try {
                level = Integer.parseInt(levelStr);
            } catch (NumberFormatException e) {
                System.err.println("❌ 无效的权限级别，使用默认值 (普通用户)");
            }
        }

        // 验证输入
        if (username.isEmpty() || password.isEmpty()) {
            System.err.println("❌ 用户名和密码不能为空！");
            return;
        }

        // 管理员权限检查 - 只有管理员用户才能创建管理员账户
        if (level == UserManager.ADMIN_LEVEL) {
            String currentUser = UserManager.getCurrentUser();
            if (currentUser == null || UserManager.isAdmin(currentUser)) {
                System.err.println("❌ 只有管理员用户才能创建管理员账户！");
                level = UserManager.NORMAL_LEVEL; // 强制设置为普通用户
                System.out.println("ℹ️ 权限已调整为普通用户级别");
            }
        }

        // 创建用户
        if (UserManager.createUser(username, password, level)) {
            System.out.println("✅ 用户 [" + username + "] 注册成功！权限级别: " +
                (level == UserManager.ADMIN_LEVEL ? "管理员" : "普通用户"));
        } else {
            System.err.println("❌ 用户 [" + username + "] 注册失败，可能用户名已存在！");
        }
    }

    /**
     * 处理用户登录
     * @param scanner 输入扫描器
     */
    private static void handleUserLogin(Scanner scanner) {
        System.out.print("请输入用户名: ");
        String username = scanner.nextLine().trim();
        System.out.print("请输入密码: ");
        String password = scanner.nextLine().trim();

        System.out.println("[DEBUG] 尝试登录用户: " + username);

        // 使用UserManager进行登录
        Session session = UserManager.login(username, password);

        // 验证用户
        if (session != null) {
            // 登录成功，保存会话
            userSessions.put(username, session);
            System.out.println("[DEBUG] 会话已保存到userSessions映射，当前映射大小: " + userSessions.size());

            String levelStr = session.getUserLevel() == UserManager.ADMIN_LEVEL ? "管理员" : "普通用户";
            System.out.println("✅ 欢迎回来, " + username + "！(权限级别: " + levelStr + ")");

            // 确认一下当前会话是否真的已激活
            Session currentSession = Session.getCurrentSession();
            if (currentSession != null) {
                System.out.println("[DEBUG] 当前活动会话用户: " + currentSession.getUsername());
            } else {
                System.err.println("[ERROR] 登录后的当前会话为null");
            }
        } else {
            System.err.println("❌ 用户名或密码错误！");
        }
    }

    /**
     * 处理用户登出
     */
    private static void handleUserLogout() {
        Session currentSession = Session.getCurrentSession();
        if (currentSession == null) {
            System.out.println("ℹ️ 您当前未登录！");
            return;
        }

        // 获取用户名
        String username = currentSession.getUsername();

        // 从会话映射中移除
        userSessions.remove(username);

        // 使用UserManager登出
        UserManager.logout(currentSession);

        System.out.println("✅ 再见, " + username + "！您已成功登出。");
    }

    // 新增备份处理方法
    private static void handleBackupCommand(Scanner scanner) {
        // 检查用户是否已登录
        if (checkUserLoggedIn()) {
            return;
        }

        try {
            System.out.print("请输入数据库名称: ");
            String dbName = scanner.nextLine().trim();
            System.out.print("请输入备份路径（完整路径）: ");
            String backupPath = scanner.nextLine().trim();

            if (FileManager.backupDatabase(dbName, backupPath)) {
                System.out.println("✅ 数据库备份成功: " + backupPath);
            } else {
                System.err.println("❌ 备份操作失败");
            }
        } catch (Exception e) {
            System.err.println("❌ 备份过程中发生错误: " + e.getMessage());
        }
    }

    // 新增重置系统数据库处理方法
    private static void handleResetSystem() {
        // 检查用户是否是管理员
        if (!checkAdminPrivilege()) {
            return;
        }

        Scanner confirmScanner = new Scanner(System.in);
        System.out.println("⚠️ 警告: 此操作将重置系统数据库，所有系统数据将丢失！");
        System.out.print("确认操作? (y/n): ");
        String confirm = confirmScanner.nextLine().trim().toLowerCase();

        if ("y".equals(confirm) || "yes".equals(confirm)) {
            System.out.println("准备重置系统数据库...");

            try {
                // 获取当前用户名用于日志
                Session currentSession = Session.getCurrentSession();
                String username = currentSession != null ? currentSession.getUsername() : null;

                System.out.println("清理所有活动会话...");

                // 登出所有用户
                for (Session session : userSessions.values()) {
                    try {
                        if (session != null) {
                            UserManager.logout(session);
                            System.out.println("已登出用户: " + session.getUsername());
                        }
                    } catch (Exception e) {
                        System.err.println("登出用户时出错: " + e.getMessage());
                    }
                }

                // 清空用户会话映射
                userSessions.clear();
                System.out.println("所有会话已清理");

                // 强制执行GC，尝试释放更多资源
                System.gc();
                System.runFinalization();

                // 等待资源释放
                Thread.sleep(500);

                // 执行系统数据库重置
                System.out.println("开始执行系统数据库重置...");
                if (systemDBEngine.resetSystemDB()) {
                    System.out.println("✅ 系统数据库已重置成功");
                } else {
                    System.err.println("❌ 系统数据库重置失败");
                }
            } catch (DBEngineException e) {
                System.err.println("❌ 系统数据库重置失败: " + e);
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));
                System.err.println("堆栈跟踪:\n" + sw.toString().replace("\t", "    "));
            } catch (InterruptedException e) {
                System.err.println("❌ 等待资源释放被中断: " + e.getMessage());
            }
        } else {
            System.out.println("❗ 操作已取消");
        }
    }

    private static void handleCreateDatabase(Scanner scanner) {
        // 检查用户是否已登录
        if (checkUserLoggedIn()) {
            return;
        }

        // 检查当前是否已选择数据库，如果已选择，则提示需要先清除当前数据库
        Session currentSession = Session.getCurrentSession();
        if (currentSession.getCurrentDatabaseName() != null || currentSession.getCurrentDatabaseOwnerName() != null) {
            String currentDbDisplay = (currentSession.getCurrentDatabaseOwnerName() != null ? currentSession.getCurrentDatabaseOwnerName() + "." : "") +
                                      (currentSession.getCurrentDatabaseName() != null ? currentSession.getCurrentDatabaseName() : "?");
            System.err.println("❌ 当前已选择数据库 [" + currentDbDisplay + "]，请先使用 'unuse' 命令清除当前数据库选择后再创建新数据库");
            return;
        }

        System.out.print("请输入数据库名称: ");
        String dbName = scanner.nextLine().trim();

        try {
            String username = currentSession.getUsername();
            int result = DatabaseManager.createDatabase(dbName, username);

            if (result == 1) {
                System.out.println("✅ 数据库 [" + dbName + "] (所有者: " + username + ") 创建成功。请使用 'USE " + username + "." + dbName + ";' 命令来选择它。");
            } else if (result == -1) {
                System.out.println("❌ 数据库已存在");
            } else {
                System.out.println("❌ 数据库创建失败 (错误码: " + result + ")");
            }
        } catch (StorageException e) {
            System.err.println("❌ 创建失败: " + e.getMessage());
        } catch (DBEngineException e) {
            System.err.println("❌ 系统引擎错误: " + e.getMessage());
        }
    }

    private static void handleCreateTable(Scanner scanner) {
        // 检查用户是否已登录
        Session session = Session.getCurrentSession();
        if (session == null) {
            System.err.println("❌ 请先登录后再执行此操作");
            return;
        }

        System.out.print("📝 表名称: ");
        String tableName = scanner.nextLine().trim();
        System.out.print("📝 字段定义 (例: id INT, name VARCHAR(20)): ");
        String columns = scanner.nextLine().trim();

        int status = session.executeUpdate("CREATE TABLE " + tableName + " (" + columns + ");");
        printStatus(status);
    }

    private static void handleInsertData(Scanner scanner) {
        // 检查用户是否已登录
        Session session = Session.getCurrentSession();
        if (session == null) {
            System.err.println("❌ 请先登录后再执行此操作");
            return;
        }

        System.out.print("📝 目标表: ");
        String tableName = scanner.nextLine().trim();
        System.out.print("📝 插入值 (例: 1, 'Alice'): ");
        String values = scanner.nextLine().trim();

        int status = session.executeUpdate("INSERT INTO " + tableName + " VALUES (" + values + ");");
        printStatus(status);
    }

    /**
     * 处理SQL命令
     *
     * @param sql SQL命令
     */
    private static void processSQL(String sql) {
        // 检查用户是否已登录
        if (checkUserLoggedIn()) {
            return;
        }

        try {
            Session currentSession = Session.getCurrentSession();
            String currentSessionDbName = currentSession.getCurrentDatabaseName();
            String currentSessionDbOwner = currentSession.getCurrentDatabaseOwnerName();

            // 显示当前会话信息，帮助调试
            String currentDbDisplay = "未选择";
            if (currentSessionDbName != null && currentSessionDbOwner != null) {
                currentDbDisplay = currentSessionDbOwner + "." + currentSessionDbName;
            } else if (currentSessionDbName != null) {
                currentDbDisplay = currentSessionDbName + " (所有者未知)";
            }
            System.out.println("[DEBUG] 当前会话状态 - 用户: " + currentSession.getUsername() +
                             ", 数据库: " + currentDbDisplay);

            // 特殊处理SHOW USERS命令
            if (sql.toUpperCase().startsWith("SHOW USERS")) {
                PrintWriter pw = null;
                UserManager.showAllUsers(currentSession.getUsername(),pw);
                return;
            }

            // 特殊处理SHOW TABLES命令
            if (sql.toUpperCase().startsWith("SHOW TABLES")) {
                String[] parts = sql.split("\\s+");
                String ownerForShow = null;
                String dbForShow = null;

                if (parts.length > 2 && parts[2].equalsIgnoreCase("FROM") && parts.length > 3) {
                    String ownerAndDbName = parts[3].replace(";", "").trim();
                    String[] dbIdentifierParts = ownerAndDbName.split("\\.");
                    if (dbIdentifierParts.length == 2) {
                        ownerForShow = dbIdentifierParts[0];
                        dbForShow = dbIdentifierParts[1];
                    } else {
                        System.err.println("❌ SHOW TABLES FROM 语法错误。数据库名需使用 'ownerName.dbName' 格式。");
                        return;
                    }
                } else {
                    ownerForShow = currentSessionDbOwner;
                    dbForShow = currentSessionDbName;
                }
                
                if (dbForShow == null || ownerForShow == null) {
                    System.err.println("❌ 错误：没有选择数据库或所有者信息不完整 (SHOW TABLES)。请使用 USE 命令。");
                    return;
                }
                DatabaseManager.showTables(ownerForShow, dbForShow);
                return;
            }

            // 特殊处理DESCRIBE/DESC表结构命令
            if (sql.toUpperCase().startsWith("DESCRIBE ") || sql.toUpperCase().startsWith("DESC ")) {
                String[] parts = sql.split("\\s+");
                if (parts.length > 1) {
                    String tableName = parts[1].replace(";", "").trim();
                    if (currentSessionDbName == null || currentSessionDbOwner == null) {
                         System.err.println("❌ 错误：没有选择数据库或所有者信息不完整 (DESCRIBE)。请使用 USE 命令。");
                         return;
                    }
                    DatabaseManager.showTableInfo(tableName, currentSessionDbOwner, currentSessionDbName);
                } else {
                    System.err.println("❌ 语法错误: 请指定表名 (DESCRIBE table_name)");
                }
                return;
            }

            // 特殊处理USE语句 - 确保会话数据库更新
            if (sql.trim().toUpperCase().startsWith("USE ")) {
                int status = currentSession.executeUpdate(sql);
                return;
            }

            // 检查是否是查询语句（SELECT开头）
            boolean isQuery = sql.trim().toUpperCase().startsWith("SELECT");


            if (isQuery) {
                // 确保当前有选择的数据库
                if (currentSessionDbName == null || currentSessionDbOwner == null) {
                    System.err.println("❌ 请先使用USE语句选择数据库 (SELECT)");
                    return;
                }

                // 执行查询
                ArrayList<ArrayList<String>> results = currentSession.executeQuery(sql);
                if (results != null && !results.isEmpty()) {
                    // 将ArrayList<ArrayList<String>>转换为List<String[]>格式
                    List<String[]> formattedResults = new ArrayList<>();
                    for (ArrayList<String> row : results) {
                        formattedResults.add(row.toArray(new String[0]));
                    }

                    // 打印查询结果（包括表头）
                    System.out.println("查询返回 " + (formattedResults.size() - 1) + " 行数据（不含表头）：");
                    printResults(formattedResults);
                } else {
                    System.out.println("查询未返回任何结果");
                }
            } else {
                // 对于CREATE TABLE和其他修改语句，确保有当前数据库
                if ((currentSessionDbName == null || currentSessionDbOwner == null) &&
                    (sql.trim().toUpperCase().startsWith("CREATE TABLE") ||
                     sql.trim().toUpperCase().startsWith("ALTER TABLE") ||
                     sql.trim().toUpperCase().startsWith("DROP TABLE") ||
                     sql.trim().toUpperCase().startsWith("INSERT"))) {
                    System.err.println("❌ 请先使用USE语句选择数据库 (DML/DDL)");
                    return;
                }

                // 执行更新
                System.out.println("[DEBUG] 执行SQL: " + sql);
                int status = currentSession.executeUpdate(sql);
                System.out.println("[DEBUG] SQL执行完成，状态码: " + status);

                if (status >= 0) {
                    System.out.println("✅ SQL执行成功，影响行数 (近似): " + status);
                } else {
                    System.err.println("❌ SQL执行失败 (SQLParser报告错误)。");
                }
            }
        } catch (Exception e) {
            // 捕获并显示SQL执行过程中的所有异常
            System.err.println("❌ SQL执行错误: " + e);
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            System.err.println("堆栈跟踪:\n" + sw.toString().replace("\t", "    "));
        }
    }

    /**
     * 检查用户是否已登录
     *
     * @return 如果未登录返回true，已登录返回false
     */
    private static boolean checkUserLoggedIn() {
        if (Session.getCurrentSession() == null) {
            System.err.println("❌ 请先登录后再执行此操作");
            return true;
        }
        return false;
    }

    /**
     * 检查是否具有管理员权限
     *
     * @return 如果是管理员返回true，否则返回false
     */
    private static boolean checkAdminPrivilege() {
        Session currentSession = Session.getCurrentSession();
        if (currentSession == null) {
            System.err.println("❌ 请先登录后再执行此操作");
            return false;
        }

        if (currentSession.getUserLevel() != UserManager.ADMIN_LEVEL) {
            System.err.println("❌ 此操作需要管理员权限");
            return false;
        }

        return true;
    }

    /**
     * 打印查询结果。
     * @param results 查询结果列表，每行为一条记录数据 (第一行为表头)
     */
    private static void printResults(List<String[]> results) {
        if (results.isEmpty()) {
            System.out.println("❗ 查询结果为空");
            return;
        }

        // 计算每列的最大宽度
        int[] columnWidths = new int[results.get(0).length];
        for (String[] row : results) {
            for (int i = 0; i < row.length; i++) {
                String cell = row[i] != null ? row[i] : "NULL";
                columnWidths[i] = Math.max(columnWidths[i], cell.length());
            }
        }

        // 打印表头横线
        printHorizontalLine(columnWidths);

        // 打印表头
        String[] header = results.get(0);
        System.out.print("| ");
        for (int i = 0; i < header.length; i++) {
            String cell = header[i] != null ? header[i] : "NULL";
            System.out.print(padRight(cell, columnWidths[i]) + " | ");
        }
        System.out.println();

        // 打印分隔线
        printHorizontalLine(columnWidths);

        // 打印数据行
        for (int rowIndex = 1; rowIndex < results.size(); rowIndex++) {
            String[] row = results.get(rowIndex);
            System.out.print("| ");
            for (int i = 0; i < row.length; i++) {
                String cell = row[i] != null ? row[i] : "NULL";
                System.out.print(padRight(cell, columnWidths[i]) + " | ");
            }
            System.out.println();
        }

        // 打印底部横线
        printHorizontalLine(columnWidths);
    }

    /**
     * 打印表格水平分隔线
     * @param columnWidths 列宽数组
     */
    private static void printHorizontalLine(int[] columnWidths) {
        System.out.print("+");
        for (int width : columnWidths) {
            System.out.print("-".repeat(width + 2) + "+");
        }
        System.out.println();
    }

    /**
     * 在字符串右侧填充空格，使其达到指定长度
     * @param s 原字符串
     * @param n 目标长度
     * @return 填充后的字符串
     */
    private static String padRight(String s, int n) {
        return String.format("%-" + n + "s", s);
    }

    /**
     * 打印 SQL 执行状态。
     * @param status 执行状态码
     */
    private static void printStatus(int status) {
        if (status == 1) {
            System.out.println("✅ SQL 执行成功！");
        } else if (status == 0) {
            System.err.println("❗ SQL 执行失败！");
        } else {
            System.err.println("❗ 未知错误！");
        }
    }

    private static void handleShowUsers() {
        // 检查用户是否已登录
        if (checkUserLoggedIn()) {
            return;
        }

        // 调用UserManager的showAllUsers方法（已包含权限检查）
        PrintWriter pw = null;
        UserManager.showAllUsers(UserManager.getCurrentUser(),pw);
    }

    private static void handleShowDatabases() {
        // 检查用户是否已登录
        if (checkUserLoggedIn()) {
            return;
        }

        // 调用DatabaseManager的showDatabases方法显示当前用户的数据库
        DatabaseManager.showDatabases(UserManager.getCurrentUser());
    }

    private static void handleDeleteDatabase(Scanner scanner) {
        // 检查用户是否已登录
        if (checkUserLoggedIn()) {
            return;
        }

        System.out.print("请输入要删除的数据库名称 (格式: ownerName.dbName 或 dbName 如果是你自己的): ");
        String dbIdentifier = scanner.nextLine().trim();
        String ownerName;
        String dbName;

        Session currentSession = Session.getCurrentSession();
        String currentUser = currentSession.getUsername();

        String[] parts = dbIdentifier.split("\\.");
        if (parts.length == 2) {
            ownerName = parts[0];
            dbName = parts[1];
        } else if (parts.length == 1) {
            ownerName = currentUser; // Default to current user if only dbName is provided
            dbName = parts[0];
        } else {
            System.err.println("❌ 无效的数据库标识符格式。请使用 'ownerName.dbName' 或 'dbName'。");
            return;
        }
        
        // 非SQL "delete_db" 命令通常只允许删除自己的库
        if (!ownerName.equals(currentUser) && !UserManager.isAdmin(currentUser)) {
             System.err.println("❌ 使用 delete_db 命令，您只能删除自己的数据库，或需要管理员权限删除他人数据库。请使用 SQL 'DROP DATABASE owner.dbName;'。");
             return;
        }

        try {
            // 确认删除操作
            System.out.print("确认要删除数据库 [" + ownerName + "." + dbName + "] 吗？此操作不可逆！(y/n): ");
            String confirm = scanner.nextLine().trim().toLowerCase();
            if (!confirm.equals("y") && !confirm.equals("yes")) {
                System.out.println("❗ 操作已取消");
                return;
            }

            // 执行删除操作 - Session.deleteDatabase is for user's own DB by non-SQL command
            // For admin or specified owner, we should call DatabaseManager directly or use SQL DROP
            // Since this is a non-SQL command, let's restrict it to owner or admin for their own DBs for now.
            // The Session.deleteDatabase method already takes only dbName and assumes current user is owner.
            // To support owner.dbName here properly, Session.deleteDatabase needs update or we call DM.
            
            int result;
            if (ownerName.equals(currentUser)) { // User deleting their own DB
                result = currentSession.deleteDatabase(dbName); // This method in Session uses this.getUsername() as owner
            } else if (UserManager.isAdmin(currentUser)) { // Admin deleting another user's DB via this command
                System.out.println("[INFO] Admin " + currentUser + " attempting to delete DB: " + ownerName + "." + dbName + " via non-SQL command.");
                // Admin bypass means DatabaseManager.deleteDatabase should be called.
                // Session.deleteDatabase(dbName) is for user's own.
                // To avoid confusion, admin should use SQL DROP DATABASE for others' DBs.
                // For this non-SQL path, let's restrict to user deleting their own.
                // Or, if we want admin to use this, then currentSession.deleteDatabase would need to be smarter or this would call DM.deleteDatabase directly.
                // For now, stick to user deleting their own via this system command path.
                // Let's adjust the Session.deleteDatabase to take ownerName if we proceed this way.
                // Given previous changes, currentSession.deleteDatabase(dbName) will pass (this.getUsername(), dbName) to DM.
                // So if admin is ownerName, it should work.
                // The issue is if admin wants to delete *another* user's DB via this *system command*.
                // Let's keep it simple: this command is for users to delete *their own* database.
                // Admins should use SQL "DROP DATABASE owner.actual_db_name;"
                System.err.println("❌ 管理员请使用 SQL 命令 'DROP DATABASE " + ownerName + "." + dbName + ";' 来删除其他用户的数据库。");
                return;
            } else {
                 System.err.println("❌ 您没有权限删除数据库 " + ownerName + "." + dbName);
                 return;
            }

            if (result == 1) {
                System.out.println("✅ 数据库 [" + ownerName + "." + dbName + "] 删除成功");
                // If deleted DB was the current one, Session.deleteDatabase should have cleared it.
            } else {
                System.out.println("❌ 数据库删除失败 (可能不存在或权限不足)。");
            }
        } catch (Exception e) {
            System.err.println("❌ 删除失败: " + e.getMessage());
        }
    }

    private static void handleUnuse() {
        // 检查用户是否已登录
        if (checkUserLoggedIn()) {
            return;
        }

        Session currentSession = Session.getCurrentSession();
        String currentDbName = currentSession.getCurrentDatabaseName();
        String currentDbOwner = currentSession.getCurrentDatabaseOwnerName();

        if (currentDbName != null || currentDbOwner != null) {
            System.out.println("[INFO] 当前数据库是: " + (currentDbOwner != null ? currentDbOwner + "." : "") + (currentDbName != null ? currentDbName : "?") );
            
            currentSession.setCurrentDatabase(null, null); // This should also trigger transaction reset if active
            System.out.println("✅ 已清除当前数据库选择。");

        } else {
            System.out.println("ℹ️ 当前没有选择数据库。");
        }
    }

    /**
     * 处理添加列操作
     *
     * @param scanner 输入扫描器
     */
    private static void handleAddColumn(Scanner scanner) {
        // 检查用户是否已登录
        if (checkUserLoggedIn()) {
            return;
        }

        // 检查当前是否选择了数据库
        Session currentSession = Session.getCurrentSession();
        String dbName = currentSession.getCurrentDatabaseName();
        String ownerName = currentSession.getCurrentDatabaseOwnerName();

        if (dbName == null || ownerName == null) {
            System.err.println("❌ 请先选择一个数据库 (USE ownerName.dbName)");
            return;
        }

        try {
            // 获取表名
            System.out.print("请输入表名: ");
            String tableName = scanner.nextLine().trim();
            if (tableName.isEmpty()) {
                System.err.println("❌ 表名不能为空");
                return;
            }

            // 获取列名
            System.out.print("请输入新列名: ");
            String columnName = scanner.nextLine().trim();
            if (columnName.isEmpty()) {
                System.err.println("❌ 列名不能为空");
                return;
            }

            // 获取数据类型
            System.out.print("请输入数据类型(VARCHAR, INT, DOUBLE等): ");
            String dataType = scanner.nextLine().trim().toUpperCase();
            if (dataType.isEmpty()) {
                System.err.println("❌ 数据类型不能为空");
                return;
            }

            // 获取列长度
            System.out.print("请输入列长度(整数，VARCHAR类型常用255): ");
            String lengthStr = scanner.nextLine().trim();
            // int length; // Length is part of dataType string for ALTER for now.
            // try {
            //     length = Integer.parseInt(lengthStr);
            //     if (length <= 0) {
            //         System.err.println("❌ 列长度必须大于0");
            //         return;
            //     }
            // } catch (NumberFormatException e) {
            //     System.err.println("❌ 列长度必须是有效的整数");
            //     return;
            // }

            // 获取是否可为空 (This non-SQL command might not easily translate to SQL ALTER syntax for nullability)
            // System.out.print("是否允许为空(y/n，默认为y): ");
            // String nullableStr = scanner.nextLine().trim().toLowerCase();
            // boolean nullable = !nullableStr.equals("n");

            // For simplicity, this non-SQL command will construct an SQL ALTER statement
            String fullDataType = dataType;
            if (dataType.equals("VARCHAR") || dataType.equals("CHAR")) {
                fullDataType += "(" + lengthStr + ")";
            }
            
            String alterSql = "ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " " + fullDataType + ";";
            System.out.println("执行SQL: " + alterSql);
            int status = currentSession.executeUpdate(alterSql);
            printStatus(status);

        } catch (Exception e) {
            System.err.println("❌ 添加列时出错: " + e.getMessage());
        }
    }

    /**
     * 处理删除列操作
     *
     * @param scanner 输入扫描器
     */
    private static void handleDropColumn(Scanner scanner) {
        // 检查用户是否已登录  、、 。。
        if (checkUserLoggedIn()) {
            return;
        }

        // 检查当前是否选择了数据库
        Session currentSession = Session.getCurrentSession();
        String dbName = currentSession.getCurrentDatabaseName();
        String ownerName = currentSession.getCurrentDatabaseOwnerName();
        if (dbName == null || ownerName == null) {
            System.err.println("❌ 请先选择一个数据库 (USE ownerName.dbName)");
            return;
        }

        try {
            // 获取表名
            System.out.print("请输入表名: ");
            String tableName = scanner.nextLine().trim();
            if (tableName.isEmpty()) {
                System.err.println("❌ 表名不能为空");
                return;
            }

            // 获取列名
            System.out.print("请输入要删除的列名: ");
            String columnName = scanner.nextLine().trim();
            if (columnName.isEmpty()) {
                System.err.println("❌ 列名不能为空");
                return;
            }

            // 确认删除
            System.out.print("确认要删除列 [" + columnName + "] 吗？此操作不可恢复(y/n): ");
            String confirm = scanner.nextLine().trim().toLowerCase();
            if (!confirm.equals("y") && !confirm.equals("yes")) {
                System.out.println("❗ 操作已取消");
                return;
            }

            String alterSql = "ALTER TABLE " + tableName + " DROP COLUMN " + columnName + ";";
            System.out.println("执行SQL: " + alterSql);
            int status = currentSession.executeUpdate(alterSql);
            printStatus(status);

        } catch (Exception e) {
            System.err.println("❌ 删除列时出错: " + e.getMessage());
        }
    }
}

